//leetcode 22

#include<iostream>
#include<vector>
#include<string>
using namespace std;
//当左括号数量小于n的时候，可以添加左括号；当右括号的数量小于左括号的数量的时候，可以添加右括号
//重点在于放置完左括号之后的回溯，当放置完左括号后递归探寻所有能够放置左括号的解
//放置完后回溯，然后再判断该位置是否可以放置右括号
//例如，（（（，首先放置了三个左括号，然后进行回溯，（（接着判断是否能够放置右括号
//如果放置右括号，则继续递归,每次递归一次都会判断放置左括号和放置右括号的情况
void backtrack(vector<string>& ans,string& s, int left, int right, int n)
{
    if(s.size()==n*2)
    {
        ans.push_back(s);
        return;
    }
    if(left<n)
    {
        s.push_back('(');
        backtrack(ans,s,left+1,right,n);
        s.pop_back();
    }
    if(right<left)
    {
        s.push_back(')');
        backtrack(ans,s,left,right+1,n);
        s.pop_back(); 
    } 
}
vector<string> generateParenthesis(int n) {
    vector<string> ans;
    string s;
    backtrack(ans,s,0,0,n);
    return ans;
}
int main()
{
    int n;
    cin>>n;
    vector<string> ans = generateParenthesis(n);
    for(auto& s:ans)
    {
        cout<<s<<" ";
    }   
    return 0;
}